<!--
 * @Author: xcl
 * @Date: 2022-04-20 18:05:17
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2022-09-23 09:13:24
 * @Description: 首页
-->

<template>
  <div>
    <cesium-map :type="2" :obt="{ debug: false }"></cesium-map>
    <div class="box">
      <el-input v-model="time"
        ><template slot="append">时间/s</template></el-input
      >
      <span>总距离：{{ long }}</span>
      <span>均速：{{ speed }} / 16.6ms每帧</span>
      <el-button type="primary" @click="setAnchor" plain>抛射锚点</el-button>
      <el-button type="warning" @click="eliminate" plain>结束</el-button>
      <el-button type="info" @click="pauseFun" plain>{{
        pause ? "继续" : "暂停"
      }}</el-button>
      <br />
      <el-button type="success" :disabled="btnShow" @click="run(null)" plain
        >开始->人</el-button
      >
      <br />
      <el-button type="success" @click="run(pathArr_fixed)" plain
        >开始->人->固定路线</el-button
      >
      <br />
      <el-button type="success" :disabled="btnShow" @click="run_camera" plain
        >开始->相机</el-button
      >
      <br />
      <el-button type="success" @click="run_cameraT" plain
        >开始->相机->固定路线</el-button
      >
      <br />
      <el-button
        type="success"
        :disabled="btnShow"
        @click="run_route(null)"
        plain
        >路线漫游</el-button
      >
      <br />
      <el-button type="success" @click="run_route(polyline_arr_fixed)" plain
        >路线漫游->固定路线</el-button
      >
    </div>
  </div>
</template>

<script>
import CesiumMap from "@/components/map/CesiumMap.vue";
export default {
  name: "Home",
  components: { "cesium-map": CesiumMap },
  data() {
    return {
      pause: false,

      btnShow: true,

      first: false,

      pathArr: [],
      // 人
      pathArr_fixed: [
        {
          destination: {
            x: 108.93967514418415,
            y: 34.23682690017577,
            z: -0.0010061544602062075,
          },
        },
        {
          destination: {
            x: 108.94118564794894,
            y: 34.23683827504988,
            z: -0.0010078765293075292,
          },
        },
        {
          destination: {
            x: 108.9411893331391,
            y: 34.237243943698154,
            z: -0.0011143567031071755,
          },
        },
        {
          destination: {
            x: 108.94129011717845,
            y: 34.23725195811504,
            z: -0.0005748558924557305,
          },
        },
        {
          destination: {
            x: 108.94131242163296,
            y: 34.23724405409908,
            z: -0.0005729517640924574,
          },
        },
        {
          destination: {
            x: 108.94176691645802,
            y: 34.2372432317797,
            z: -0.0005609632067316674,
          },
        },
        {
          destination: {
            x: 108.94175662247429,
            y: 34.23775852325556,
            z: -0.0010986232639433415,
          },
        },
        {
          destination: {
            x: 108.94237301692584,
            y: 34.2377767929467,
            z: -0.0011263973889915832,
          },
        },
        {
          destination: {
            x: 108.94238378652547,
            y: 34.23684961617665,
            z: -0.00102756161338452,
          },
        },
        {
          destination: {
            x: 108.94177858150641,
            y: 34.23684284585977,
            z: -0.0009931339760332533,
          },
        },
      ],
      long: 0,
      speed: 0,
      time: 20,
      state: null,
      position: {
        x: 108.937008,
        y: 34.233938,
        z: 0,
      },

      position_camera: null,

      startTime: null,

      upORdown: null,

      Heading: 6.236132643031626,

      // 相机
      arr_fixed: [
        {
          destination: {
            x: 108.935888,
            y: 34.205496,
            z: 1861.4646841528795,
          },
          orientation: {
            heading: 0.05883366319008054,
            pitch: -0.44581391043838714,
            roll: 0.000010753492032833378,
          },
        },
        {
          destination: {
            x: 108.935302,
            y: 34.290002,
            z: 2022.2209371631793,
          },
          orientation: {
            heading: 2.971012408999713,
            pitch: -0.485973947739784,
            roll: 0.00017616932998532064,
          },
        },
        {
          destination: {
            x: 108.79605,
            y: 34.249117,
            z: 11776.116922341467,
          },
          orientation: {
            heading: 1.552338403071455,
            pitch: -0.6923181607268618,
            roll: 0.00045288776229579497,
          },
        },
        {
          destination: {
            x: 108.929182,
            y: 34.105711,
            z: 12439.614248794358,
          },
          orientation: {
            heading: 6.212812539825943,
            pitch: -0.7495962538122019,
            roll: 0.0011458634380838717,
          },
        },
      ],

      // 折线点位
      polyline_arr: [],
      polyline_arr_fixed: [
        {
          destination: {
            x: 108.93185248927261,
            y: 34.22300085635333,
            z: -0.004807702732886461,
          },
          orientation: {
            heading: 6.2760569087228095,
            pitch: -1.3902824745222793,
            roll: 0.00032264057354058906,
          },
        },
        {
          destination: {
            x: 108.93207076931787,
            y: 34.23000720979334,
            z: -0.008979037895191241,
          },
          orientation: {
            heading: 6.2760569087228095,
            pitch: -1.3902824745222793,
            roll: 0.00032264057354058906,
          },
        },
        {
          destination: {
            x: 108.93915766939439,
            y: 34.23003899819657,
            z: -0.007581764341267556,
          },
          orientation: {
            heading: 6.2760569087228095,
            pitch: -1.3902824745222793,
            roll: 0.00032264057354058906,
          },
        },
        {
          destination: {
            x: 108.93911026211907,
            y: 34.22293898801262,
            z: -0.003267075613049044,
          },
          orientation: {
            heading: 6.2760569087228095,
            pitch: -1.3902824745222793,
            roll: 0.00032264057354058906,
          },
        },
        {
          destination: {
            x: 108.94670360764309,
            y: 34.2228586502513,
            z: -0.0017004224895892464,
          },
          orientation: {
            heading: 6.2760569087228095,
            pitch: -1.3902824745222793,
            roll: 0.00032264057354058906,
          },
        },
        {
          destination: {
            x: 108.94686852738484,
            y: 34.230146634870444,
            z: -0.006987688148931684,
          },
          orientation: {
            heading: 6.2760569087228095,
            pitch: -1.3902824745222793,
            roll: 0.00032264057354058906,
          },
        },
      ],
      polyline_next: null,

      // 路线点位
      position_route: null,

      aa: [],
    };
  },
  computed: {},
  props: {},
  watch: {},
  created() {},
  mounted() {
    // console.log(window.vmCesiumViewer);
    this.addModel();

    // const viewer = window.vmCesiumViewer;
    // var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    // let self = this;
    // handler.setInputAction(function (CLICK) {
    //   let point = viewer.scene.globe.pick(
    //     viewer.camera.getPickRay(CLICK.position),
    //     viewer.scene
    //   );
    //   var ellipsoid = viewer.scene.globe.ellipsoid;
    //   var cartesian3 = new Cesium.Cartesian3(point.x, point.y, point.z);
    //   var cartographic = ellipsoid.cartesianToCartographic(cartesian3);
    //   var lat = Cesium.Math.toDegrees(cartographic.latitude);
    //   var lng = Cesium.Math.toDegrees(cartographic.longitude);
    //   var alt = cartographic.height;
    //   self.aa.push({
    //     destination: {
    //       x: lng,
    //       y: lat,
    //       z: alt,
    //     },
    //   });
    //   console.log(self.aa);
    // }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  },
  methods: {
    // 添加模型
    addModel() {
      const viewer = window.vmCesiumViewer;
      let tileset = viewer.entities.add({
        id: "model",
        position: new Cesium.CallbackProperty(this.getPositin, false),
        // orientation: Cesium.Transforms.headingPitchRollQuaternion(
        //   Cesium.Cartesian3.fromDegrees(108.937008, 34.233938, 0),
        //   new Cesium.HeadingPitchRoll(6.236132643031626, 0.0, 0.0)
        // ),
        orientation: new Cesium.CallbackProperty(this.orientation, false),
        name: "model",
        model: {
          uri: "./static/model_y/Cesium_Man.glb",
          scale: 10,
          runAnimations: new Cesium.CallbackProperty(this.runAnimations, false),
        },
      });
      viewer.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(
          108.93854,
          34.23309,
          102.76662287810355
        ),
        orientation: {
          heading: 5.236132643545357,
          pitch: -0.524166666153441,
          roll: 6.28318530615313,
        },
      });
      viewer.scene.postUpdate.addEventListener(this.renderCallback);
      viewer.clock.shouldAnimate = true;
    },
    runAnimations() {
      return this.state == "run" && !this.pause;
    },
    orientation() {
      return Cesium.Transforms.headingPitchRollQuaternion(
        Cesium.Cartesian3.fromDegrees(
          this.position.x,
          this.position.y,
          this.position.z
        ),
        new Cesium.HeadingPitchRoll(this.Heading, 0.0, 0.0)
      );
    },
    getPositin() {
      if (this.state == "run" && !this.pause) {
        const viewer = window.vmCesiumViewer;
        if (this.first) {
          this.state = null;
          this.first = false;
          setTimeout(() => {
            this.state = "run";
          }, 1100);
        } else {
          if (!viewer.trackedEntity) {
            viewer.trackedEntity = viewer.entities.getById("model");
            setTimeout(() => {
              window.vmCesiumViewer.camera.zoomOut(350);
            }, 10);
          }
          if (
            this.position.x == this.pathArr[0].destination.x &&
            this.position.y == this.pathArr[0].destination.y
            // && this.position.z == this.pathArr[0].destination.z
          ) {
            this.polyline_arr.push(JSON.parse(JSON.stringify(this.position)));
            this.polyline_next = null;

            if (this.pathArr[1])
              this.Heading =
                ((this.angle(this.position, this.pathArr[1].destination) +
                  270) /
                  360) *
                // 6.236132643031626
                6.29;
            this.pathArr.shift();

            if (!this.pathArr.length) {
              this.eliminate();
              return Cesium.Cartesian3.fromDegrees(
                this.position.x,
                this.position.y,
                this.position.z
              );
            }
            this.startTime = new Date();
          } else {
            this.position = this.getPointBySpan(
              this.position,
              this.pathArr[0].destination,
              ((new Date() - this.startTime) / 16.66) * this.speed
            );

            this.startTime = new Date();

            this.polyline_next = this.position;
          }
        }
      }
      return Cesium.Cartesian3.fromDegrees(
        this.position.x,
        this.position.y,
        this.position.z
      );
    },
    // cesium 每帧回调
    renderCallback() {
      if (this.pause) return;
      if (this.state == "run_camera") this.run_camera_fun();
      if (this.state == "run_route") this.run_route_fun();
    },
    run_camera_fun() {
      const viewer = window.vmCesiumViewer;
      if (
        this.position_camera.x == this.pathArr[0].destination.x &&
        this.position_camera.y == this.pathArr[0].destination.y &&
        this.position_camera.z == this.pathArr[0].destination.z
      ) {
        this.polyline_arr.push(
          JSON.parse(JSON.stringify(this.position_camera))
        );
        this.polyline_next = null;

        let self = this;
        this.state = null;

        if (this.pathArr[1]) {
          let heading =
            (this.angle(this.position_camera, this.pathArr[1].destination) /
              360) *
            6.29;

          viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(
              this.position_camera.x,
              this.position_camera.y,
              this.position_camera.z
            ),
            orientation: {
              heading: heading,
              pitch: this.pathArr[0].orientation.pitch,
              roll: this.pathArr[0].orientation.roll,
            },
            complete: () => {
              if (self.pathArr.length) self.state = "run_camera";
              self.startTime = new Date();
            },
          });

          let time =
            (this.quadrant(
              { destination: this.position_camera },
              this.pathArr[1]
            ) /
              this.speed) *
            16.66;
          let next = this.pathArr[1].destination;
          if (this.position_camera.z > next.z)
            this.upORdown = (this.position_camera.z - next.z) / (time / 16.66);
          else
            this.upORdown = (next.z - this.position_camera.z) / (time / 16.66);
        } else {
          viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(
              this.pathArr[0].destination.x,
              this.pathArr[0].destination.y,
              this.pathArr[0].destination.z
            ),
            orientation: this.pathArr[0].orientation,
          });
        }

        this.pathArr.shift();
        if (!this.pathArr.length) this.eliminate();
        return;
      }

      this.position_camera = this.getPointBySpan(
        this.position_camera,
        this.pathArr[0].destination,
        ((new Date() - this.startTime) / 16.66) * this.speed,
        ((new Date() - this.startTime) / 16.66) * this.upORdown
      );

      this.polyline_next = this.position_camera;

      viewer.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(
          this.position_camera.x,
          this.position_camera.y,
          this.position_camera.z
        ),
        orientation: {
          heading: viewer.scene.camera.heading,
          pitch: viewer.scene.camera.pitch,
          roll: viewer.scene.camera.roll,
        },
      });
      this.startTime = new Date();
    },
    run_route_fun2() {
      const viewer = window.vmCesiumViewer;
      if (this.first) {
        this.state = null;
        this.first = false;
        setTimeout(() => {
          this.state = "run_route";
        }, 1100);
      } else {
        if (
          this.position_route.x == this.pathArr[0].destination.x &&
          this.position_route.y == this.pathArr[0].destination.y &&
          this.position_route.z == this.pathArr[0].destination.z
        ) {
          this.polyline_arr.push(
            JSON.parse(JSON.stringify(this.position_route))
          );
          this.polyline_next = null;

          let self = this;
          this.state = null;

          if (this.pathArr[1]) {
            let OBserved = this.getOBservedPoint(
              this.position_route,
              this.pathArr[1].destination,
              40,
              0.002
            );
            viewer.camera.flyTo({
              destination: OBserved.destination,
              orientation: OBserved.orientation,
              complete: () => {
                if (self.pathArr.length) self.state = "run_route";
                self.startTime = new Date();
              },
            });

            let time =
              (this.quadrant(
                { destination: this.position_route },
                this.pathArr[1]
              ) /
                this.speed) *
              16.66;
            let next = this.pathArr[1].destination;
            if (this.position_route.z > next.z)
              this.upORdown = (this.position_route.z - next.z) / (time / 16.66);
            else
              this.upORdown = (next.z - this.position_route.z) / (time / 16.66);
          }

          this.pathArr.shift();
          if (!this.pathArr.length) this.eliminate();
          this.startTime = new Date();
          return;
        }
        this.position_route = this.getPointBySpan(
          this.position_route,
          this.pathArr[0].destination,
          ((new Date() - this.startTime) / 16.66) * this.speed
        );
        this.polyline_next = this.position_route;
        if (
          !(
            this.position_route.x == this.pathArr[0].destination.x &&
            this.position_route.y == this.pathArr[0].destination.y
          )
        ) {
          let OBserved = this.getOBservedPoint(
            this.position_route,
            this.pathArr[0].destination,
            40,
            0.002
          );

          viewer.camera.setView(OBserved);
        }
        this.startTime = new Date();
      }
    },
    run_route_fun() {
      const viewer = window.vmCesiumViewer;
      if (this.first) {
        this.state = null;
        this.first = false;
        setTimeout(() => {
          this.state = "run_route";
        }, 1100);
      } else {
        if (
          this.position_route.x == this.pathArr[0].destination.x &&
          this.position_route.y == this.pathArr[0].destination.y &&
          this.position_route.z == this.pathArr[0].destination.z
        ) {
          // 折线
          this.polyline_arr.push(
            JSON.parse(JSON.stringify(this.position_route))
          );
          this.polyline_next = null;

          // 观察点位
          if (this.pathArr[1]) {
            let parallel = this.parallel(
              this.position_route,
              this.pathArr[1].destination,
              this.getCameraPoint().destination
            );
            let OBserved = this.getOBservedPoint(
              this.position_route,
              this.pathArr[1].destination,
              40,
              0.002,
              !parallel,
              ((new Date() - this.startTime) / 16.66) * this.speed
            );
            viewer.camera.setView(OBserved);
          }

          this.pathArr.shift();
          if (!this.pathArr.length) this.eliminate();
          this.startTime = new Date();
          return;
        }
        this.position_route = this.getPointBySpan(
          this.position_route,
          this.pathArr[0].destination,
          ((new Date() - this.startTime) / 16.66) * this.speed
        );
        this.polyline_next = this.position_route;
        if (
          !(
            this.position_route.x == this.pathArr[0].destination.x &&
            this.position_route.y == this.pathArr[0].destination.y
          )
        ) {
          let parallel = this.parallel(
            this.position_route,
            this.pathArr[0].destination,
            this.getCameraPoint().destination
          );
          let OBserved = this.getOBservedPoint(
            this.position_route,
            this.pathArr[0].destination,
            40,
            0.002,
            !parallel,
            ((new Date() - this.startTime) / 16.66) * this.speed
          );

          viewer.camera.setView(OBserved);
        }
        this.startTime = new Date();
      }
    },
    // 点a为圆心,b c 是否在a点两侧
    parallel(a, b, c) {
      let forward = this.angle(a, b),
        backwards = this.angle(a, c);
      backwards == 0 ? (backwards = 360) : "";
      if (backwards > forward)
        return (
          backwards > forward + 180 - 0.1 && backwards < forward + 180 + 0.1
        );
      else
        return (
          forward > backwards + 180 - 0.1 && forward < backwards + 180 + 0.1
        );
    },
    pauseFun() {
      this.pause = !this.pause;
      if (!this.pause) {
        this.startTime = new Date();
      } else {
        const viewer = window.vmCesiumViewer;
        viewer.trackedEntity = undefined;
      }
    },
    // 路线漫游
    run_route(pathArr) {
      const viewer = window.vmCesiumViewer;
      this.state = "run_route";
      this.first = true;
      this.startTime = new Date();

      if (pathArr) {
        this.pathArr = JSON.parse(JSON.stringify(pathArr));
        let arr = this.pathArr;
        for (let i = 0; i < arr.length; i++) {
          const e = arr[i];
          if (i < arr.length - 1) {
            this.long += this.quadrant(e, arr[i + 1]);
            this.speed = this.long / ((this.time * 1000) / 16.66);
          }
        }
      }
      this.pathArr.forEach((e) => {
        e.destination.z = 0;
      });
      this.billboard(this.pathArr);
      this.position_route = this.pathArr[0].destination;

      let OBserved = this.getOBservedPoint(
        this.position_route,
        this.pathArr[1].destination,
        40,
        0.002
      );

      viewer.camera.setView(OBserved);

      this.polyline_arr = [];
      this.polyline_next = null;
      setTimeout(() => {
        this.polyline();
      }, 150);
    },
    /**
     * 获取观察点位
     * @param {被观察点位} now
     * @param {被观察点位的驶向点位} next
     * @param {镜头倾斜角度} tilt
     * @param {离被观察点位间距} spacing
     * @param {镜头 - 被观察点位 - 被观察点位的驶向点位 是否组成拐点} inflection
     * @param {步长} speed
     * @returns 观察点位
     */
    getOBservedPoint(now, next, tilt, spacing, inflection, speed) {
      now = JSON.parse(JSON.stringify(now));
      next = JSON.parse(JSON.stringify(next));
      let OBserved = this.getPointBySpan(now, next, -spacing);
      OBserved.z += this.trigonometric(tilt, {
        type: "b",
        num: spacing * 111000,
      }).a;
      if (inflection) {
        OBserved = this.getPointBySpan(
          this.getCameraPoint().destination,
          OBserved,
          speed
        );
        return {
          destination: Cesium.Cartesian3.fromDegrees(
            OBserved.x,
            OBserved.y,
            OBserved.z
          ),
          orientation: {
            heading: (this.angle(OBserved, now) / 360) * 6.29,
            pitch: (tilt / 360) * -6.29,
            roll: 0,
          },
        };
      } else
        return {
          destination: Cesium.Cartesian3.fromDegrees(
            OBserved.x,
            OBserved.y,
            OBserved.z
          ),
          orientation: {
            heading: (this.angle(OBserved, next) / 360) * 6.29,
            pitch: (tilt / 360) * -6.29,
            roll: 0,
          },
        };
    },
    // 广告牌
    billboard(arr) {
      const viewer = window.vmCesiumViewer;
      if (viewer.dataSources.getByName("pupu").length > 0)
        viewer.dataSources.remove(
          viewer.dataSources.getByName("pupu")[0],
          true
        );

      let dataSource = new Cesium.CustomDataSource("pupu");
      viewer.dataSources.add(dataSource);
      for (let i = 0; i < arr.length; i++) {
        const element = arr[i].destination;
        let text;
        if (i == 0) text = "起点";
        else if (i == arr.length - 1) text = "终点";
        else text = "转折点" + i;
        dataSource.entities.add({
          position: new Cesium.Cartesian3.fromDegrees(
            element.x,
            element.y,
            1.2
          ),
          name: "billboard",
          billboard: {
            image: "./static/img/point.png",
            show: true,
            scale: 2.0,
            width: 32,
            height: 32,
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
          },
          label: {
            show: true,
            text,
            scale: 1.0,
            fillColor: Cesium.Color.DARKORANGE,
            pixelOffset: new Cesium.Cartesian2(0, 45),
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
          },
        });
      }
    },
    // 添加广告牌
    addBillboardGraphics(position) {
      const viewer = window.vmCesiumViewer;
      viewer.entities.add({
        position,
        name: "billboard",
        billboard: {
          image: "./static/img/aircraft.png",
          show: true,
          scale: 2.0,
          width: 32,
          height: 32,
        },
      });
    },
    // 根据步长获得下一点位
    getPointBySpan(now, next, span, UD) {
      now = JSON.parse(JSON.stringify(now));
      next = JSON.parse(JSON.stringify(next));

      if (UD) {
        if (now.z > next.z) {
          now.z -= UD;
          if (now.z < next.z) now.z = next.z;
        } else {
          now.z += UD;
          if (now.z > next.z) now.z = next.z;
        }
      }

      let x, y;
      if (now.x == next.x) {
        if (now.y > next.y) {
          now.y -= span;
          if (now.y < next.y) now.y = next.y;
        } else {
          now.y += span;
          if (now.y > next.y) now.y = next.y;
        }
      } else if (now.y == next.y) {
        if (now.x > next.x) {
          now.x -= span;
          if (now.x < next.x) now.x = next.x;
        } else {
          now.x += span;
          if (now.x > next.x) now.x = next.x;
        }
      } else {
        if (now.x > next.x) {
          if (now.y > next.y) {
            x = now.x - next.x;
            y = now.y - next.y;
            let point = this.trigonometric(this.unTrigonometric(x, y).a, {
              type: "c",
              num: span,
            });
            now.x -= point.a;
            now.y -= point.b;
            if (now.x < next.x) now.x = next.x;
            if (now.y < next.y) now.y = next.y;
          } else {
            x = now.x - next.x;
            y = next.y - now.y;
            let point = this.trigonometric(this.unTrigonometric(y, x).a, {
              type: "c",
              num: span,
            });
            now.x -= point.b;
            now.y += point.a;
            if (now.x < next.x) now.x = next.x;
            if (now.y > next.y) now.y = next.y;
          }
        } else {
          if (now.y > next.y) {
            x = next.x - now.x;
            y = now.y - next.y;
            let point = this.trigonometric(this.unTrigonometric(y, x).a, {
              type: "c",
              num: span,
            });
            now.x += point.b;
            now.y -= point.a;
            if (now.x > next.x) now.x = next.x;
            if (now.y < next.y) now.y = next.y;
          } else {
            x = next.x - now.x;
            y = next.y - now.y;
            let point = this.trigonometric(this.unTrigonometric(x, y).a, {
              type: "c",
              num: span,
            });
            now.x += point.a;
            now.y += point.b;
            if (now.x > next.x) now.x = next.x;
            if (now.y > next.y) now.y = next.y;
          }
        }
      }

      return now;
    },
    // 动态折线
    polyline() {
      if (
        !(
          this.polyline_arr.length >= 2 ||
          (this.polyline_arr.length && this.polyline_next)
        )
      ) {
        setTimeout(() => {
          this.polyline();
        }, 150);
        return;
      }
      const viewer = window.vmCesiumViewer;
      if (viewer.entities.getById("Polyline"))
        viewer.entities.removeById("Polyline");
      viewer.entities.add({
        id: "Polyline",
        polyline: {
          positions: new Cesium.CallbackProperty(this.getPolylineArr, false),
          // this.getPolylineArr(),
          width: 10,
          // arcType: Cesium.ArcType.RHUMB,
          material: Cesium.Color.GREEN,
        },
      });
    },
    getPolylineArr() {
      let arr = [];
      this.polyline_arr.forEach((e) => arr.push(e.x, e.y, 1));
      if (this.polyline_next)
        arr.push(this.polyline_next.x, this.polyline_next.y, 1);
      return Cesium.Cartesian3.fromDegreesArrayHeights(arr);
    },
    // 开始漫游 -> 相机
    run_camera() {
      const viewer = window.vmCesiumViewer;
      this.state = "run_camera";
      this.startTime = new Date();
      this.position_camera = this.pathArr[0].destination;
      this.billboard(this.pathArr);

      viewer.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(
          this.pathArr[0].destination.x,
          this.pathArr[0].destination.y,
          this.pathArr[0].destination.z
        ),
        orientation: this.pathArr[0].orientation,
      });

      this.polyline_arr = [];
      this.polyline_next = null;
      setTimeout(() => {
        this.polyline();
      }, 150);
    },
    run_cameraT() {
      this.pathArr = JSON.parse(JSON.stringify(this.arr_fixed));
      let arr = this.pathArr;
      for (let i = 0; i < arr.length; i++) {
        const e = arr[i];
        if (i < arr.length - 1) {
          this.long += this.quadrant(e, arr[i + 1]);
          this.speed = this.long / ((this.time * 1000) / 16.66);
        }
      }
      this.run_camera();
      this.polyline_arr = [];
      this.polyline_next = null;
      setTimeout(() => {
        this.polyline();
      }, 150);
    },
    // 开始漫游
    run(pathArr) {
      this.state = "run";
      this.first = true;

      if (pathArr) {
        this.pathArr = JSON.parse(JSON.stringify(pathArr));
        let arr = this.pathArr;
        for (let i = 0; i < arr.length; i++) {
          const e = arr[i];
          if (i < arr.length - 1) {
            this.long += this.quadrant(e, arr[i + 1]);
            this.speed = this.long / ((this.time * 1000) / 16.66);
          }
        }
      }

      this.billboard(this.pathArr);

      this.position = this.pathArr[0].destination;
      this.position.z = 0;

      const viewer = window.vmCesiumViewer;
      viewer.trackedEntity = viewer.entities.getById("model");
      setTimeout(() => {
        window.vmCesiumViewer.camera.zoomOut(350);
      }, 10);

      this.polyline_arr = [];
      this.polyline_next = null;
      setTimeout(() => {
        this.polyline();
      }, 150);
    },
    // 清除
    eliminate() {
      this.state = null;
      this.long = 0;
      this.speed = 0;
      this.pathArr = [];
      this.btnShow = true;
      this.pause = false;
      // const viewer = window.vmCesiumViewer;
      // if (viewer.entities.getById("Polyline"))
      //   viewer.entities.removeById("Polyline");

      setTimeout(() => {
        const viewer = window.vmCesiumViewer;
        viewer.trackedEntity = undefined;
      }, 10);
    },
    // 获取相机点位
    getCameraPoint() {
      let viewer = window.vmCesiumViewer;
      var head = viewer.scene.camera.heading;
      var pitch = viewer.scene.camera.pitch;
      var roll = viewer.scene.camera.roll;
      var position = viewer.scene.camera.positionCartographic;
      var longitude = Cesium.Math.toDegrees(position.longitude).toFixed(6);
      var latitude = Cesium.Math.toDegrees(position.latitude).toFixed(6);
      let height = position.height;
      // console.log(Number(longitude), Number(latitude), Number(height));
      return {
        destination: {
          x: Number(longitude),
          y: Number(latitude),
          z: Number(height),
        },
        orientation: {
          heading: head,
          pitch: pitch,
          roll: roll,
        },
      };
    },
    // 抛射相机锚点
    setAnchor() {
      this.pathArr.push(this.getCameraPoint());

      if (this.pathArr.length > 1) this.btnShow = false;

      // this.$message.success("标记成功");
      let arr = this.pathArr;
      for (let i = 0; i < arr.length; i++) {
        const e = arr[i];
        if (i < arr.length - 1) {
          this.long += this.quadrant(e, arr[i + 1]);
          this.speed = this.long / ((this.time * 1000) / 16.66);
        }
      }
      console.log(this.pathArr);
    },
    // 获取两点之间路程
    quadrant(now, next) {
      let x =
          now.destination.x > next.destination.x
            ? now.destination.x - next.destination.x
            : next.destination.x - now.destination.x,
        y =
          now.destination.y > next.destination.y
            ? now.destination.y - next.destination.y
            : next.destination.y - now.destination.y;
      if (
        now.destination.x == next.destination.x &&
        now.destination.y == next.destination.y
      ) {
        return 0;
      } else if (now.destination.x == next.destination.x) {
        return y;
      } else if (now.destination.y == next.destination.y) {
        return x;
      } else {
        return this.trigonometric(this.unTrigonometric(x, y).a, {
          type: "a",
          num: x,
        }).c;
      }
    },
    // 反三角函数
    unTrigonometric(a, b, c) {
      let angle = {};

      if (a && b) angle.a = (Math.atan(a / b) * 180) / Math.PI;
      else if (a && c) angle.a = (Math.asin(a / c) * 180) / Math.PI;
      else if (b && c) angle.a = (Math.acos(b / c) * 180) / Math.PI;

      if (angle.a) angle.b = 90 - angle.a;
      angle.c = 90;

      return angle;
    },
    // 三角函数
    trigonometric(angle = 37, params = { type: "a", num: 3 }) {
      let a, b, c;
      let sin = Math.sin(angle * (Math.PI / 180));
      let cos = Math.cos(angle * (Math.PI / 180));

      if (params.type == "a") {
        a = params.num;
        c = a / sin;
        b = c * cos;
      } else if (params.type == "c") {
        c = params.num;
        a = c * sin;
        b = c * cos;
      } else if (params.type == "b") {
        b = params.num;
        c = b / cos;
        a = sin * c;
      }
      return { a, b, c };
    },
    // 两点的角度 点a为圆心
    angle(a, b) {
      if (a.x == b.x && a.y == b.y) return null;
      else if (a.x == b.x) return a.y > b.y ? 180 : 0;
      else if (a.y == b.y) return a.x > b.x ? 270 : 90;
      else {
        if (a.y > b.y) {
          if (a.x > b.x)
            return this.unTrigonometric(a.x - b.x, a.y - b.y).a + 180;
          else return this.unTrigonometric(a.y - b.y, b.x - a.x).a + 90;
        } else {
          if (a.x > b.x)
            return this.unTrigonometric(b.y - a.y, a.x - b.x).a + 270;
          else return this.unTrigonometric(b.x - a.x, b.y - a.y).a;
        }
      }
    },
  },
  beforeDestroy() {},
};
</script>

<style lang="less" scoped>
#home {
  height: calc(100vh - 60px);
  overflow: hidden;
  overflow-y: auto;
  background-color: white !important;
}
.box {
  background-color: #9be8e799;
  padding: 10px;
  border-radius: 5px;
  position: fixed;
  top: 200px;
  left: 50px;
  span {
    color: white;
    display: block;
  }
}
</style>